package com.cjack.frenchexcel.service;

import cn.hutool.core.util.StrUtil;
import com.cjack.frenchexcel.config.ErrorCodeDefine;
import com.cjack.frenchexcel.dao.ConsumerRecordDao;
import com.cjack.frenchexcel.dao.CooperativeNumberDao;
import com.cjack.frenchexcel.dao.MooncardCardDao;
import com.cjack.frenchexcel.dao.UserAdminDao;
import com.cjack.frenchexcel.exception.CommonException;
import com.cjack.frenchexcel.model.CooperativeNumberModel;
import com.cjack.frenchexcel.table.AdminUserTable;
import com.cjack.frenchexcel.table.ConsumerRecordTable;
import com.cjack.frenchexcel.table.CooperativeNumberTable;
import com.cjack.frenchexcel.table.MooncardCardTable;
import com.cjack.frenchexcel.util.ModelUtils;
import com.google.api.client.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Created by root on 10/5/19
 */
@Service
public class CooperativeNumberService {

    @Autowired
    private CooperativeNumberDao dao;
    @Autowired
    private ConsumerRecordDao consumerRecordDao;
    @Autowired
    private MooncardCardDao mooncardCardDao;
    @Autowired
    private UserAdminDao userAdminDao;


    public List<CooperativeNumberModel> list( CooperativeNumberModel condition) {
        Specification< CooperativeNumberTable> specification = handleConditon( condition);
        Sort sort = new Sort( Sort.Direction.ASC, "number");
        return ModelUtils.copyListModel( dao.findAll( specification, sort), CooperativeNumberModel.class);
    }

    public void save( CooperativeNumberModel model) throws CommonException {
        model.setNameRule(com.cjack.frenchexcel.util.StringUtils.toUpperCase(model.getNameRule()));
        CooperativeNumberTable table;
        //员工编号 & 合作商编号
        CooperativeNumberTable jobNumberAndNumber = dao.findByJobNumberAndNumber(model.getJobNumber(), model.getNumber());
        //员工编号 & 合作商简称
        CooperativeNumberTable jobNumberAndName = dao.findByJobNumberAndName(model.getJobNumber(), model.getName());

        if( model.getId() == null){
            //新增合作商数据时候: 当前写入的 [员工编号 & 合作商编号] 或者 [员工编号 & 合作商简称] 已经被占用，抛出错误信息
            if (jobNumberAndNumber != null || jobNumberAndName != null) {
                throw new CommonException( ErrorCodeDefine.INTERFACE_COMMON_ERROR, "合作商编号或者合作商编号重复");
            }
            // 新增 -
            table = ModelUtils.copySignModel( model, CooperativeNumberTable.class);
            table.setUpdateTime( new Date());
            table.setCreateTime( new Date());
        }else{
            if ((jobNumberAndNumber != null && !Objects.equals(jobNumberAndNumber.getId(), model.getId()))
                    || (jobNumberAndName != null && !Objects.equals(jobNumberAndName.getId(), model.getId()))) {
                throw new CommonException( ErrorCodeDefine.INTERFACE_COMMON_ERROR, "合作商编号或者合作商编号重复");
            }
            // 更新 -
            table = dao.findOne( model.getId());
            table.setUpdateTime( new Date());
            ModelUtils.copySignModel( model, table);
        }
        //检查名称包含规则是否有重复
        //this.checkRepeat( table);
        dao.save( table);
    }

    public List<CooperativeNumberModel> listForSelect() {
        Sort sort = new Sort( Sort.Direction.ASC, "name");
        return ModelUtils.copyListModel(dao.findAll(sort), CooperativeNumberModel.class);
    }

    public List<CooperativeNumberModel> listForSelectByConsumerRecordId(Long consumerRecordId) {
        //查询消费记录数据
        ConsumerRecordTable recordTable = consumerRecordDao.findOne(consumerRecordId);
        if (recordTable == null || StrUtil.isEmpty(recordTable.getCarteIdentifiant())) {
            return Lists.newArrayList();
        }

        //根据卡号查询卡信息
        MooncardCardTable cardInfo = mooncardCardDao.findByBankNo(recordTable.getCarteIdentifiant());
        if (cardInfo == null) {
            return Lists.newArrayList();
        }

        //根据员工id查询员工信息
        AdminUserTable adminUserTable = userAdminDao.findOne(cardInfo.getAdminUserId());
        if (adminUserTable == null || StrUtil.isEmpty(adminUserTable.getJobNumber())) {
            return Lists.newArrayList();
        }

        Sort sort = new Sort( Sort.Direction.ASC, "name");
        return ModelUtils.copyListModel(dao.findAllByJobNumber(adminUserTable.getJobNumber()), CooperativeNumberModel.class);
    }

    public List<CooperativeNumberModel> listForSelectByJobNumber(String jobNumber) {
        Sort sort = new Sort( Sort.Direction.ASC, "name");
        return ModelUtils.copyListModel(dao.findAllByJobNumber(jobNumber), CooperativeNumberModel.class);
    }

    //判断名称规则是否重复
    private void checkRepeat( CooperativeNumberTable table) throws CommonException {
        for( String nameRule : table.getNameRule().split( ",")){
            List<CooperativeNumberTable> exsitDatas = null;
            if( table.getId() == null){
                exsitDatas = dao.findAllByNameRuleLike( "%" + nameRule + "%");
            }else{
                exsitDatas = dao.findAllByNameRuleLikeAndIdNot( "%" + nameRule + "%", table.getId());
            }
            if( exsitDatas != null && exsitDatas.size() > 0){
                throw new CommonException( ErrorCodeDefine.INTERFACE_COMMON_ERROR, "名称包含规则[" + nameRule + "]已经存在其他供应商编号，添加失败");
            }
        }
    }

    public CooperativeNumberModel getByNumber( String number){
        if( number == null || number.equals( "")){
            return null;
        }
        CooperativeNumberTable table = dao.getByNumber( number);
        if( table == null){
            return null;
        }
        return ModelUtils.copySignModel( table, CooperativeNumberModel.class);
    }

    /**
     * 组装查询条件
     * @param condition
     * @return
     */
    private Specification<CooperativeNumberTable> handleConditon(CooperativeNumberModel condition){
        Specification< CooperativeNumberTable> specification = new Specification< CooperativeNumberTable>() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                Predicate predicate = cb.conjunction();
                if( !StringUtils.isEmpty( condition.getNumber())){//模糊搜索
                    predicate.getExpressions().add( cb.like( root.get( "number").as( String.class), "%" + condition.getNumber() + "%"));
                }
                if( !StringUtils.isEmpty( condition.getName())){//模糊搜索
                    predicate.getExpressions().add( cb.like( root.get( "name").as( String.class), "%" + condition.getName() + "%"));
                }
                if( !StringUtils.isEmpty( condition.getNameRule())){//模糊搜索
                    predicate.getExpressions().add( cb.like( root.get( "nameRule").as( String.class), "%" + condition.getNameRule() + "%"));
                }
                if( !StringUtils.isEmpty( condition.getJobNumber())){//模糊搜索
                    predicate.getExpressions().add( cb.like( root.get( "jobNumber").as( String.class), "%" + condition.getJobNumber() + "%"));
                }
                return predicate;
            }
        };
        return specification;
    }

    public void del( CooperativeNumberModel model){
        dao.delete( model.getId());
    }

    public CooperativeNumberModel getById(Long id) {
        return ModelUtils.copySignModel(dao.getOne(id), CooperativeNumberModel.class);
    }
}
